package br.edu.ufcg.nokia.battleship;

import br.edu.ufcg.nokia.battleship.excecoes.LimiteTabuleiroExcedidoException;
import br.edu.ufcg.nokia.battleship.excecoes.NavioSobrepostoException;

/**
 * Classe que representa um computador como um jogador.
 * @author Miguel Queiroga, Jackson Azevedo, Edmilson Almeida, Jose Luis
 * @version 1.0
 */

public class JogadorComputador extends Jogador {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 2247992510070092363L;
	
	/*
	 * Variaveis usadas para guardar informacoes usadas na "inteligencia" do Jogador tipo Computador.
	 * direcaoAtaque: indica em qual direcao ocorre o atauque do jogador, os valores sao 1 para a direita, 2 para
	 * cima, 3 para a esquerda, 4 para baixo.
	 */
	private byte direcaoAtaque = 0;
	private int xAtacado;
	private int yAtacado;
	private int contadorAtaque = 1;
	
	/**
	 * Construtor para um computador que eh um jogador.
	 * @param tabuleiro o tabuleiro para este jogador.
	 */
	public JogadorComputador(Tabuleiro tabuleiro){
		super.meuTabuleiro = tabuleiro;
		int indice = 2;
		while(indice <= 6){
			int x = this.numeroAleatorio();
			int y = this.numeroAleatorio();
			boolean orientacao = false;
			if( Math.random() > 0.5 ){
				orientacao = true;
			}
			try {
				if (super.meuTabuleiro.adicionaNavio(x, y, orientacao, indice)) indice ++;
			} catch (LimiteTabuleiroExcedidoException e) {
			} catch (NavioSobrepostoException e) {
			}
		}
	}
	
	/**
	 * Responsavel pelo ataque ao tabuleiro do oponente. Esse metodo implementa varios casos de ataque, dependendo
	 * do historico de ataques realizados. Se um navio e atingido, uma variavel estatica e modificada, e na proxima
	 * vez que o metodo for chamado o restante do navio sera destruido. 
	 * @param outroTabuleiro uma referencia ao tabuleiro do oponente.
	 * @return <tt>0</tt> se tentou atacar uma regiao ja atacada, <tt>1</tt> se a regiao atacada correspondia a 
	 * agua e <tt>2</tt> se na regiao atacada encontrava-se alguma embarcacao.
	 */
	public byte ataca(Tabuleiro outroTabuleiro){
		
		byte retorno = 1;
		int x = this.numeroAleatorio();
		int y = this.numeroAleatorio();
		
		switch(direcaoAtaque){
			case 0:						// O computador ataca aleatoriamente, se acertar garda a posicao		
				retorno = super.ataca(x,y,outroTabuleiro);
				if(retorno == 2){
					direcaoAtaque++;
					xAtacado = x;
					yAtacado = y;
				}
				break;
			case 1:						// O computador ataca a regiao a direita da posicao gurdada 
				if (yAtacado + contadorAtaque >10){
					direcaoAtaque ++;
					contadorAtaque = 1;
					return 0;
				}
				retorno = super.ataca(xAtacado,yAtacado + contadorAtaque,outroTabuleiro);
				if((retorno !=2 )&&(contadorAtaque > 1)){
					direcaoAtaque +=2;
					contadorAtaque = 1;
					break;
				}
				if(retorno != 2){
					direcaoAtaque++;
					contadorAtaque = 1;
				}else{
					contadorAtaque++;
				}
			    break;
			case 2:						// O computador ataca a regiao acima da posicao guardada
				if (xAtacado - contadorAtaque < 1){
					direcaoAtaque ++;
					contadorAtaque = 1;
					return 0;
				}
				retorno = super.ataca(xAtacado - contadorAtaque,yAtacado,outroTabuleiro);
				if((retorno != 2 )&&(contadorAtaque > 1)){
				contadorAtaque = 1;
					direcaoAtaque +=2;
					break;
				}
				if(retorno != 2){
					direcaoAtaque++;
					contadorAtaque = 1;
				}else{
					contadorAtaque++;
				}
			    break;
			case 3:						// O computador ataca a regiao a esquerda da posicao gurdada
				if (yAtacado - contadorAtaque < 1){
					direcaoAtaque ++;
					contadorAtaque = 1;
					return 0;
				}
				retorno = super.ataca(xAtacado,yAtacado - contadorAtaque,outroTabuleiro);
				if(retorno != 2){
					direcaoAtaque++;
					contadorAtaque = 1;
				}
				else{
					contadorAtaque++;
				}
			    break;
			case 4:						// O computador ataca a regiao abaixo da posicao gurdada
				if (xAtacado + contadorAtaque >10){
					direcaoAtaque = 0;
					contadorAtaque = 1;
					return 0;
				}
				retorno = super.ataca(xAtacado + contadorAtaque,yAtacado,outroTabuleiro);
				if(retorno != 2){
					direcaoAtaque = 0;
					contadorAtaque = 1;
				}
				else{
					contadorAtaque++;
				}
			    break;
		}
		if (retorno != 0){
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {}
		}
		return retorno;
	}

	/**
	 * Geracao de numero aleatorio para coordenadas. O numero gerado varia de 1 ate 10. 
	 * @return um numero aleatorio
	 */

	private int numeroAleatorio(){
		return (int)((Math.random()*10)+1);
	}
}